package main;

import exception.BadNodeReachedException;
import graph.Graph;
import graph.Node;

import java.io.IOException;
import java.util.ArrayList;

import platform.Platform;
import task_system.TaskSystem;
import utils.FileHelper;
import algorithm.Attractors;
import algorithm.Scheduler;

public class Program {
	private String path;
	private TaskSystem ts;
	private Attractors attractors;
	private Scheduler scheduler;
	private ArrayList<ArrayList<Node>> bad_states;
	private ArrayList<ArrayList<Node>> reached_states;
	private Graph graph;

	
	public Program(int m, String path){
			this.path = path;
			init(m, path);
	}
	
	private void init(int m, String path){
		try {
			ts = FileHelper.getInstance().extract_system(path);
			//set the number of available processors
			Platform.getInstance().set_m(m);
			//get an instance for the graph corresponding to the task system
			graph = new Graph(ts);
			//get an instance of the attractors algorithm on the graph
			attractors = new Attractors(graph);
			//get an instance of the test for scheduling strategies 
			scheduler = new Scheduler(graph, attractors);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public boolean run(){
		//consider only the systems of a certain size
		if(ts.tasks().size() == Main.system_size ){
			try {
				//calculate the failure states
				graph.calculate_bad_nodes();
				//run attractors algorithm
				bad_states = attractors.run();
				//test the scheduling strategies
				reached_states = scheduler.run();
			} catch (BadNodeReachedException e) {
				e.printStackTrace();
				System.exit(0);
			}
			return true;
		}
		else{
			bad_states = null;
		}
		return false;
		
	}
	
	public void print(){
		try {
			
			if(bad_states != null && reached_states != null){
				
				System.out.println("preparing string");
				String to_print = "";
				for(Node n : bad_states.get(0)){
					to_print += n.toString();
					to_print += "\n";
				}
				
				FileHelper.getInstance().writeFile(to_print, ""+path+"_"+ Platform.getInstance().m() +"_failure_states_system.txt");
				System.out.println("preparing string");
				to_print = "";
				for(Node n : bad_states.get(1)){
					to_print += n.toString();
					to_print += "\n";
				}
				FileHelper.getInstance().writeFile(to_print, ""+path+"_"+ Platform.getInstance().m() +"_failure_states_scheduler.txt");

				System.out.println("preparing string");
				to_print = "";
				for(Node n : reached_states.get(0)){
					to_print += n.toString();
					to_print += "\n";
				}
				FileHelper.getInstance().writeFile(to_print, ""+path+"_"+ Platform.getInstance().m() +"_reached_states_system.txt");
	
				System.out.println("preparing string");
				to_print = "";
				for(Node n : reached_states.get(1)){
					to_print += n.toString();
					to_print += "\n";
				}
				FileHelper.getInstance().writeFile(to_print, ""+path+"_"+ Platform.getInstance().m() +"_reached_states_scheduler.txt");
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
